package io.github.echarts.model.theme;

import io.github.echarts.model.context.ConfigurationContext;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 默认值提供者抽象基类
 * <p>
 * 为DefaultValueProvider接口提供通用实现，简化具体提供者的开发。
 * 包含基础的默认值处理逻辑和默认值注册机制。
 * </p>
 * 
 * @param <T> 配置类型
 */
public abstract class AbstractDefaultValueProvider<T> implements DefaultValueProvider<T> {
    
    /**
     * 支持的配置类型
     */
    private final Class<T> supportedType;
    
    /**
     * 默认值映射表
     */
    private final Map<String, Object> defaultValues = new HashMap<>();
    
    /**
     * 构造函数
     * 
     * @param supportedType 支持的配置类型
     */
    protected AbstractDefaultValueProvider(Class<T> supportedType) {
        this.supportedType = supportedType;
        initDefaultValues();
    }
    
    /**
     * 初始化默认值
     * 子类应该在此方法中注册默认值
     */
    protected abstract void initDefaultValues();
    
    @Override
    public Class<T> getSupportedType() {
        return supportedType;
    }
    
    @Override
    public void applyDefaults(T config, ConfigurationContext context) {
        if (config == null) {
            return;
        }
        
        // 应用默认值前的预处理
        beforeApplyDefaults(config, context);
        
        // 应用基本默认值
        applyBasicDefaults(config, context);
        
        // 应用数据驱动的默认值
        applyDataDrivenDefaults(config, context);
        
        // 应用默认值后的后处理
        afterApplyDefaults(config, context);
    }
    
    /**
     * 应用默认值前的预处理
     * 
     * @param config 配置对象
     * @param context 配置上下文
     */
    protected void beforeApplyDefaults(T config, ConfigurationContext context) {
        // 默认空实现，子类可以覆盖
    }
    
    /**
     * 应用基本默认值
     * 根据defaultValues映射表应用通用默认值
     * 
     * @param config 配置对象
     * @param context 配置上下文
     */
    protected void applyBasicDefaults(T config, ConfigurationContext context) {
        // 此方法使用Java反射机制应用默认值
        // 子类可以覆盖或扩展此方法
        
        for (Map.Entry<String, Object> entry : defaultValues.entrySet()) {
            String propertyName = entry.getKey();
            Object defaultValue = entry.getValue();
            
            try {
                // 尝试获取getter方法
                String getterName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                java.lang.reflect.Method getter = config.getClass().getMethod(getterName);
                
                // 如果当前值为null，则应用默认值
                Object currentValue = getter.invoke(config);
                if (currentValue == null) {
                    // 尝试获取setter方法
                    String setterName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                    java.lang.reflect.Method setter = config.getClass().getMethod(setterName, defaultValue.getClass());
                    
                    // 应用默认值
                    setter.invoke(config, defaultValue);
                }
            } catch (Exception e) {
                // 忽略反射异常，可能是属性不存在或类型不匹配
            }
        }
    }
    
    /**
     * 应用数据驱动的默认值
     * 根据上下文中的数据特征应用智能默认值
     * 
     * @param config 配置对象
     * @param context 配置上下文
     */
    protected void applyDataDrivenDefaults(T config, ConfigurationContext context) {
        // 默认空实现，子类应该覆盖此方法以提供数据驱动的默认值
    }
    
    /**
     * 应用默认值后的后处理
     * 
     * @param config 配置对象
     * @param context 配置上下文
     */
    protected void afterApplyDefaults(T config, ConfigurationContext context) {
        // 默认空实现，子类可以覆盖
    }
    
    @Override
    public void ensureCompleteness(T config, ConfigurationContext context) {
        // 默认实现，子类应该覆盖此方法以确保配置完整性
    }
    
    @Override
    public void applyTheme(T config, Theme theme) {
        // 默认实现，子类应该覆盖此方法以应用主题样式
    }
    
    /**
     * 注册默认值
     * 
     * @param propertyName 属性名
     * @param defaultValue 默认值
     */
    protected void registerDefaultValue(String propertyName, Object defaultValue) {
        if (propertyName != null && defaultValue != null) {
            defaultValues.put(propertyName, defaultValue);
        }
    }
    
    /**
     * 获取所有注册的默认值
     * 
     * @return 不可修改的默认值映射
     */
    protected Map<String, Object> getDefaultValues() {
        return Collections.unmodifiableMap(defaultValues);
    }
    
    /**
     * 获取特定属性的默认值
     * 
     * @param propertyName 属性名
     * @return 默认值，如果未找到则返回null
     */
    protected Object getDefaultValue(String propertyName) {
        return defaultValues.get(propertyName);
    }
} 